(************************************************************************)
(*  Copyright(c) Filip Lundeholm 2010                                   *)
(*          All Rights Reserved                                         *)
(*                                                                      *)
(*  Revision History:                                                   *)
(*    2010-11-03    v0.2:   first public version                        *)
(************************************************************************)

unit psopas_variable;

{$mode objfpc}{$H+}

interface
uses fgl,math;
const TRUNCPLUSONE = 1.0;

type
 TSetValue = procedure(value:double) of object;

 TVariable = class
 private
    FValue:pointer;
    FMin,FMax,FAdjustedMin,FAdjustedMax:double;
    FIsTrunced:boolean;

    procedure SetValueDouble(value:double);
    procedure SetValueInteger(value:double);
    procedure SetValueByte(value:double);
    procedure setMin(value:double);
    procedure setMax(value:double);
 public
    setValue : TSetValue;

    property Min:double read FMin write setMin;
    property Max:double read FMax write setMax;
    property AdjustedMin:double read FAdjustedMin;
    property AdjustedMax:double read FAdjustedMax;

    constructor create(var value:double);
    constructor create(var value:integer);
    constructor create(var value:byte);
 end;


TVariableList   =  specialize TFPGList<TVariable>;

implementation
    constructor TVariable.create(var value:Double);
    begin
        FValue := @value;
        setValue := @SetValueDouble;
        Min := -10000;
        Max := 10000;
        FIsTrunced := false;
    end;

    constructor TVariable.create(var value:Integer);
    begin
        FValue := @value;
        setValue := @SetValueInteger;
        Min := -10000;
        Max := 10000;
        FIsTrunced := true;
    end;

    constructor TVariable.create(var value:Byte);
    begin
        FValue := @value;
        setValue := @SetValueByte;
        Min := 0;
        Max := 255;
        FIsTrunced := true;
    end;

    procedure TVariable.setMin(value:double);
    begin
      FMin := value;
      FAdjustedMin := value;
    end;

    procedure TVariable.setMax(value:double);
    begin
      FMax := value;
      FAdjustedMax := value;
      if FIsTrunced then
        FAdjustedMax := value + TRUNCPLUSONE;
    end;

    procedure TVariable.SetValueDouble(value:double);
    begin
      double(FValue^) := value;
    end;

    procedure TVariable.SetValueInteger(value:double);
    begin
      integer(FValue^) := trunc(value);
    end;

    procedure TVariable.SetValueByte(value:double);
    begin
      byte(FValue^) := byte(trunc(value));
    end;

end.

